//! # 增强的指标收集器
//!
//! 提供企业级的指标收集功能，包括：
//! * APM 性能监控指标
//! * 自动 HTTP 请求指标
//! * 自定义业务指标
//! * 指标聚合和采样
//! * 高性能无锁收集

use crate::collector::{MetricsCollector, MetricFamily, MetricType, MetricValue, Labels, Metric};
use async_trait::async_trait;
use rustcloud_core::{ServiceResult, ServiceError};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::{Arc, atomic::{AtomicU64, AtomicUsize, Ordering}};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::RwLock;
use tracing::{debug, info, warn};

/// 增强的指标收集器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnhancedCollectorConfig {
    /// 是否启用自动 HTTP 指标
    pub enable_http_metrics: bool,
    /// 是否启用 JVM 兼容指标
    pub enable_jvm_metrics: bool,
    /// 是否启用应用指标
    pub enable_app_metrics: bool,
    /// 指标保留时间（秒）
    pub metric_retention: u64,
    /// 最大指标数量
    pub max_metrics: usize,
    /// 聚合间隔（秒）
    pub aggregation_interval: u64,
    /// 是否启用采样
    pub enable_sampling: bool,
    /// 采样率
    pub sampling_rate: f64,
    /// 默认直方图桶
    pub default_histogram_buckets: Vec<f64>,
    /// 默认摘要分位数
    pub default_summary_quantiles: Vec<f64>,
}

impl Default for EnhancedCollectorConfig {
    fn default() -> Self {
        Self {
            enable_http_metrics: true,
            enable_jvm_metrics: true,
            enable_app_metrics: true,
            metric_retention: 3600, // 1小时
            max_metrics: 50000,
            aggregation_interval: 15, // 15秒
            enable_sampling: false,
            sampling_rate: 1.0,
            default_histogram_buckets: vec![
                0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, f64::INFINITY
            ],
            default_summary_quantiles: vec![0.5, 0.9, 0.95, 0.99],
        }
    }
}

/// 增强的指标收集器
pub struct EnhancedMetricsCollector {
    config: EnhancedCollectorConfig,
    metrics: Arc<RwLock<HashMap<String, MetricFamily>>>,
    counters: Arc<RwLock<HashMap<String, Arc<AtomicCounter>>>>,
    gauges: Arc<RwLock<HashMap<String, Arc<AtomicGauge>>>>,
    histograms: Arc<RwLock<HashMap<String, Arc<AtomicHistogram>>>>,
    summaries: Arc<RwLock<HashMap<String, Arc<AtomicSummary>>>>,
    
    // APM 相关指标
    http_requests_total: Arc<AtomicU64>,
    http_request_duration: Arc<RwLock<Vec<f64>>>,
    active_connections: Arc<AtomicUsize>,
    
    // 应用指标
    app_info: Arc<RwLock<HashMap<String, String>>>,
}

/// 原子计数器
pub struct AtomicCounter {
    value: AtomicU64,
    labels: Labels,
    help: String,
}

impl AtomicCounter {
    pub fn new(help: String, labels: Labels) -> Self {
        Self {
            value: AtomicU64::new(0),
            labels,
            help,
        }
    }

    pub fn inc(&self) {
        self.add(1.0);
    }

    pub fn add(&self, value: f64) {
        let int_value = (value * 1000.0) as u64; // 保留3位小数精度
        self.value.fetch_add(int_value, Ordering::Relaxed);
    }

    pub fn get(&self) -> f64 {
        self.value.load(Ordering::Relaxed) as f64 / 1000.0
    }

    pub fn reset(&self) {
        self.value.store(0, Ordering::Relaxed);
    }
}

/// 原子测量仪
pub struct AtomicGauge {
    value: AtomicU64, // 使用 u64 存储 f64 的位表示
    labels: Labels,
    help: String,
}

impl AtomicGauge {
    pub fn new(help: String, labels: Labels) -> Self {
        Self {
            value: AtomicU64::new(0),
            labels,
            help,
        }
    }

    pub fn set(&self, value: f64) {
        self.value.store(value.to_bits(), Ordering::Relaxed);
    }

    pub fn inc(&self) {
        self.add(1.0);
    }

    pub fn dec(&self) {
        self.add(-1.0);
    }

    pub fn add(&self, delta: f64) {
        loop {
            let current = self.value.load(Ordering::Relaxed);
            let current_float = f64::from_bits(current);
            let new_value = current_float + delta;
            
            if self.value.compare_exchange_weak(
                current, 
                new_value.to_bits(), 
                Ordering::Relaxed, 
                Ordering::Relaxed
            ).is_ok() {
                break;
            }
        }
    }

    pub fn get(&self) -> f64 {
        f64::from_bits(self.value.load(Ordering::Relaxed))
    }
}

/// 原子直方图
pub struct AtomicHistogram {
    buckets: Vec<(f64, AtomicU64)>,
    sum: AtomicU64, // 存储 f64 的位表示
    count: AtomicU64,
    labels: Labels,
    help: String,
}

impl AtomicHistogram {
    pub fn new(help: String, labels: Labels, buckets: Vec<f64>) -> Self {
        let bucket_counters = buckets
            .into_iter()
            .map(|upper| (upper, AtomicU64::new(0)))
            .collect();

        Self {
            buckets: bucket_counters,
            sum: AtomicU64::new(0),
            count: AtomicU64::new(0),
            labels,
            help,
        }
    }

    pub fn observe(&self, value: f64) {
        // 更新总数和总和
        self.count.fetch_add(1, Ordering::Relaxed);
        
        loop {
            let current_sum = self.sum.load(Ordering::Relaxed);
            let current_float = f64::from_bits(current_sum);
            let new_sum = current_float + value;
            
            if self.sum.compare_exchange_weak(
                current_sum,
                new_sum.to_bits(),
                Ordering::Relaxed,
                Ordering::Relaxed
            ).is_ok() {
                break;
            }
        }

        // 更新桶计数
        for (upper_bound, counter) in &self.buckets {
            if value <= *upper_bound {
                counter.fetch_add(1, Ordering::Relaxed);
            }
        }
    }

    pub fn get_buckets(&self) -> Vec<(f64, u64)> {
        self.buckets
            .iter()
            .map(|(upper, counter)| (*upper, counter.load(Ordering::Relaxed)))
            .collect()
    }

    pub fn get_sum(&self) -> f64 {
        f64::from_bits(self.sum.load(Ordering::Relaxed))
    }

    pub fn get_count(&self) -> u64 {
        self.count.load(Ordering::Relaxed)
    }
}

/// 原子摘要
pub struct AtomicSummary {
    observations: Arc<RwLock<Vec<f64>>>,
    sum: AtomicU64,
    count: AtomicU64,
    quantiles: Vec<f64>,
    labels: Labels,
    help: String,
    max_age: Duration,
    last_cleanup: Arc<RwLock<SystemTime>>,
}

impl AtomicSummary {
    pub fn new(help: String, labels: Labels, quantiles: Vec<f64>) -> Self {
        Self {
            observations: Arc::new(RwLock::new(Vec::new())),
            sum: AtomicU64::new(0),
            count: AtomicU64::new(0),
            quantiles,
            labels,
            help,
            max_age: Duration::from_secs(600), // 10分钟
            last_cleanup: Arc::new(RwLock::new(SystemTime::now())),
        }
    }

    pub async fn observe(&self, value: f64) {
        // 更新总数和总和
        self.count.fetch_add(1, Ordering::Relaxed);
        
        loop {
            let current_sum = self.sum.load(Ordering::Relaxed);
            let current_float = f64::from_bits(current_sum);
            let new_sum = current_float + value;
            
            if self.sum.compare_exchange_weak(
                current_sum,
                new_sum.to_bits(),
                Ordering::Relaxed,
                Ordering::Relaxed
            ).is_ok() {
                break;
            }
        }

        // 添加观察值
        let mut observations = self.observations.write().await;
        observations.push(value);

        // 定期清理过期数据
        let now = SystemTime::now();
        let last_cleanup = *self.last_cleanup.read().await;
        if now.duration_since(last_cleanup).unwrap_or_default() > Duration::from_secs(60) {
            observations.retain(|_| true); // 简化实现，实际应该根据时间戳过滤
            *self.last_cleanup.write().await = now;
        }
    }

    pub async fn get_quantiles(&self) -> Vec<(f64, f64)> {
        let observations = self.observations.read().await;
        if observations.is_empty() {
            return self.quantiles.iter().map(|&q| (q, 0.0)).collect();
        }

        let mut sorted = observations.clone();
        sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));

        self.quantiles
            .iter()
            .map(|&quantile| {
                let index = ((sorted.len() - 1) as f64 * quantile) as usize;
                (quantile, sorted[index])
            })
            .collect()
    }

    pub fn get_sum(&self) -> f64 {
        f64::from_bits(self.sum.load(Ordering::Relaxed))
    }

    pub fn get_count(&self) -> u64 {
        self.count.load(Ordering::Relaxed)
    }
}

impl EnhancedMetricsCollector {
    /// 创建增强的指标收集器
    pub fn new(config: EnhancedCollectorConfig) -> Self {
        Self {
            config,
            metrics: Arc::new(RwLock::new(HashMap::new())),
            counters: Arc::new(RwLock::new(HashMap::new())),
            gauges: Arc::new(RwLock::new(HashMap::new())),
            histograms: Arc::new(RwLock::new(HashMap::new())),
            summaries: Arc::new(RwLock::new(HashMap::new())),
            
            http_requests_total: Arc::new(AtomicU64::new(0)),
            http_request_duration: Arc::new(RwLock::new(Vec::new())),
            active_connections: Arc::new(AtomicUsize::new(0)),
            
            app_info: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// 创建或获取计数器
    pub async fn counter(&self, name: &str, help: &str, labels: Labels) -> ServiceResult<Arc<AtomicCounter>> {
        let key = format!("{}:{:?}", name, labels);
        let mut counters = self.counters.write().await;
        
        if let Some(counter) = counters.get(&key) {
            return Ok(counter.clone());
        }

        let counter = Arc::new(AtomicCounter::new(help.to_string(), labels));
        counters.insert(key, counter.clone());
        
        debug!("Created counter: {}", name);
        Ok(counter)
    }

    /// 创建或获取测量仪
    pub async fn gauge(&self, name: &str, help: &str, labels: Labels) -> ServiceResult<Arc<AtomicGauge>> {
        let key = format!("{}:{:?}", name, labels);
        let mut gauges = self.gauges.write().await;
        
        if let Some(gauge) = gauges.get(&key) {
            return Ok(gauge.clone());
        }

        let gauge = Arc::new(AtomicGauge::new(help.to_string(), labels));
        gauges.insert(key, gauge.clone());
        
        debug!("Created gauge: {}", name);
        Ok(gauge)
    }

    /// 创建或获取直方图
    pub async fn histogram(&self, name: &str, help: &str, labels: Labels, buckets: Option<Vec<f64>>) -> ServiceResult<Arc<AtomicHistogram>> {
        let key = format!("{}:{:?}", name, labels);
        let mut histograms = self.histograms.write().await;
        
        if let Some(histogram) = histograms.get(&key) {
            return Ok(histogram.clone());
        }

        let histogram_buckets = buckets.unwrap_or_else(|| self.config.default_histogram_buckets.clone());
        let histogram = Arc::new(AtomicHistogram::new(help.to_string(), labels, histogram_buckets));
        histograms.insert(key, histogram.clone());
        
        debug!("Created histogram: {}", name);
        Ok(histogram)
    }

    /// 创建或获取摘要
    pub async fn summary(&self, name: &str, help: &str, labels: Labels, quantiles: Option<Vec<f64>>) -> ServiceResult<Arc<AtomicSummary>> {
        let key = format!("{}:{:?}", name, labels);
        let mut summaries = self.summaries.write().await;
        
        if let Some(summary) = summaries.get(&key) {
            return Ok(summary.clone());
        }

        let summary_quantiles = quantiles.unwrap_or_else(|| self.config.default_summary_quantiles.clone());
        let summary = Arc::new(AtomicSummary::new(help.to_string(), labels, summary_quantiles));
        summaries.insert(key, summary.clone());
        
        debug!("Created summary: {}", name);
        Ok(summary)
    }

    /// 记录 HTTP 请求指标
    pub async fn record_http_request(&self, method: &str, path: &str, status: u16, duration: Duration) -> ServiceResult<()> {
        if !self.config.enable_http_metrics {
            return Ok(());
        }

        let mut labels = HashMap::new();
        labels.insert("method".to_string(), method.to_string());
        labels.insert("path".to_string(), path.to_string());
        labels.insert("status".to_string(), status.to_string());

        // 记录请求总数
        let requests_counter = self.counter(
            "http_requests_total",
            "Total number of HTTP requests",
            labels.clone()
        ).await?;
        requests_counter.inc();

        // 记录请求时长
        let duration_histogram = self.histogram(
            "http_request_duration_seconds",
            "HTTP request duration in seconds",
            labels.clone(),
            None
        ).await?;
        duration_histogram.observe(duration.as_secs_f64());

        // 记录响应大小（模拟）
        let size_histogram = self.histogram(
            "http_response_size_bytes",
            "HTTP response size in bytes",
            labels,
            Some(vec![100.0, 1024.0, 10240.0, 102400.0, 1048576.0, f64::INFINITY])
        ).await?;
        size_histogram.observe(1024.0); // 模拟 1KB 响应

        Ok(())
    }

    /// 记录数据库查询指标
    pub async fn record_database_query(&self, operation: &str, table: &str, duration: Duration, success: bool) -> ServiceResult<()> {
        let mut labels = HashMap::new();
        labels.insert("operation".to_string(), operation.to_string());
        labels.insert("table".to_string(), table.to_string());
        labels.insert("status".to_string(), if success { "success" } else { "error" }.to_string());

        // 查询总数
        let queries_counter = self.counter(
            "database_queries_total",
            "Total number of database queries",
            labels.clone()
        ).await?;
        queries_counter.inc();

        // 查询时长
        let duration_histogram = self.histogram(
            "database_query_duration_seconds",
            "Database query duration in seconds",
            labels,
            Some(vec![0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, f64::INFINITY])
        ).await?;
        duration_histogram.observe(duration.as_secs_f64());

        Ok(())
    }

    /// 记录缓存指标
    pub async fn record_cache_operation(&self, operation: &str, cache_name: &str, hit: bool) -> ServiceResult<()> {
        let mut labels = HashMap::new();
        labels.insert("operation".to_string(), operation.to_string());
        labels.insert("cache".to_string(), cache_name.to_string());
        labels.insert("result".to_string(), if hit { "hit" } else { "miss" }.to_string());

        let cache_counter = self.counter(
            "cache_operations_total",
            "Total number of cache operations",
            labels
        ).await?;
        cache_counter.inc();

        Ok(())
    }

    /// 设置应用信息
    pub async fn set_app_info(&self, key: String, value: String) -> ServiceResult<()> {
        let mut app_info = self.app_info.write().await;
        app_info.insert(key, value);
        Ok(())
    }

    /// 获取活跃连接数
    pub fn get_active_connections(&self) -> usize {
        self.active_connections.load(Ordering::Relaxed)
    }

    /// 增加活跃连接数
    pub fn inc_active_connections(&self) {
        self.active_connections.fetch_add(1, Ordering::Relaxed);
    }

    /// 减少活跃连接数
    pub fn dec_active_connections(&self) {
        self.active_connections.fetch_sub(1, Ordering::Relaxed);
    }

    /// 清理过期指标
    pub async fn cleanup_metrics(&self) -> ServiceResult<()> {
        let now = SystemTime::now();
        let retention = Duration::from_secs(self.config.metric_retention);

        // 这里应该实现具体的清理逻辑
        // 由于原子类型没有时间戳，简化实现
        debug!("Metrics cleanup completed");
        Ok(())
    }
}

#[async_trait]
impl MetricsCollector for EnhancedMetricsCollector {
    async fn register_metric(&self, name: &str, help: &str, metric_type: MetricType, labels: Labels) -> ServiceResult<()> {
        match metric_type {
            MetricType::Counter => {
                self.counter(name, help, labels).await?;
            }
            MetricType::Gauge => {
                self.gauge(name, help, labels).await?;
            }
            MetricType::Histogram => {
                self.histogram(name, help, labels, None).await?;
            }
            MetricType::Summary => {
                self.summary(name, help, labels, None).await?;
            }
        }
        Ok(())
    }

    async fn record_counter(&self, name: &str, value: f64, labels: Labels) -> ServiceResult<()> {
        let counter = self.counter(name, "", labels).await?;
        counter.add(value);
        Ok(())
    }

    async fn set_gauge(&self, name: &str, value: f64, labels: Labels) -> ServiceResult<()> {
        let gauge = self.gauge(name, "", labels).await?;
        gauge.set(value);
        Ok(())
    }

    async fn inc_gauge(&self, name: &str, value: f64, labels: Labels) -> ServiceResult<()> {
        let gauge = self.gauge(name, "", labels).await?;
        gauge.add(value);
        Ok(())
    }

    async fn dec_gauge(&self, name: &str, value: f64, labels: Labels) -> ServiceResult<()> {
        let gauge = self.gauge(name, "", labels).await?;
        gauge.add(-value);
        Ok(())
    }

    async fn observe_histogram(&self, name: &str, value: f64, labels: Labels) -> ServiceResult<()> {
        let histogram = self.histogram(name, "", labels, None).await?;
        histogram.observe(value);
        Ok(())
    }

    async fn observe_summary(&self, name: &str, value: f64, labels: Labels) -> ServiceResult<()> {
        let summary = self.summary(name, "", labels, None).await?;
        summary.observe(value).await;
        Ok(())
    }

    async fn gather(&self) -> ServiceResult<Vec<MetricFamily>> {
        let mut families = Vec::new();

        // 收集计数器
        let counters = self.counters.read().await;
        let mut counter_families: HashMap<String, MetricFamily> = HashMap::new();
        
        for (key, counter) in counters.iter() {
            let name = key.split(':').next().unwrap_or(key);
            let family = counter_families.entry(name.to_string()).or_insert_with(|| MetricFamily {
                name: name.to_string(),
                help: counter.help.clone(),
                metric_type: MetricType::Counter,
                metrics: Vec::new(),
            });
            
            family.metrics.push(Metric {
                name: name.to_string(),
                help: counter.help.clone(),
                metric_type: MetricType::Counter,
                value: MetricValue::Counter(counter.get()),
                labels: counter.labels.clone(),
                timestamp: SystemTime::now(),
            });
        }
        families.extend(counter_families.into_values());

        // 收集测量仪
        let gauges = self.gauges.read().await;
        let mut gauge_families: HashMap<String, MetricFamily> = HashMap::new();
        
        for (key, gauge) in gauges.iter() {
            let name = key.split(':').next().unwrap_or(key);
            let family = gauge_families.entry(name.to_string()).or_insert_with(|| MetricFamily {
                name: name.to_string(),
                help: gauge.help.clone(),
                metric_type: MetricType::Gauge,
                metrics: Vec::new(),
            });
            
            family.metrics.push(Metric {
                name: name.to_string(),
                help: gauge.help.clone(),
                metric_type: MetricType::Gauge,
                value: MetricValue::Gauge(gauge.get()),
                labels: gauge.labels.clone(),
                timestamp: SystemTime::now(),
            });
        }
        families.extend(gauge_families.into_values());

        // 收集直方图
        let histograms = self.histograms.read().await;
        let mut histogram_families: HashMap<String, MetricFamily> = HashMap::new();
        
        for (key, histogram) in histograms.iter() {
            let name = key.split(':').next().unwrap_or(key);
            let family = histogram_families.entry(name.to_string()).or_insert_with(|| MetricFamily {
                name: name.to_string(),
                help: histogram.help.clone(),
                metric_type: MetricType::Histogram,
                metrics: Vec::new(),
            });
            
            family.metrics.push(Metric {
                name: name.to_string(),
                help: histogram.help.clone(),
                metric_type: MetricType::Histogram,
                value: MetricValue::Histogram {
                    count: histogram.get_count(),
                    sum: histogram.get_sum(),
                    buckets: histogram.get_buckets(),
                },
                labels: histogram.labels.clone(),
                timestamp: SystemTime::now(),
            });
        }
        families.extend(histogram_families.into_values());

        // 收集摘要
        let summaries = self.summaries.read().await;
        let mut summary_families: HashMap<String, MetricFamily> = HashMap::new();
        
        for (key, summary) in summaries.iter() {
            let name = key.split(':').next().unwrap_or(key);
            let family = summary_families.entry(name.to_string()).or_insert_with(|| MetricFamily {
                name: name.to_string(),
                help: summary.help.clone(),
                metric_type: MetricType::Summary,
                metrics: Vec::new(),
            });
            
            family.metrics.push(Metric {
                name: name.to_string(),
                help: summary.help.clone(),
                metric_type: MetricType::Summary,
                value: MetricValue::Summary {
                    count: summary.get_count(),
                    sum: summary.get_sum(),
                    quantiles: summary.get_quantiles().await,
                },
                labels: summary.labels.clone(),
                timestamp: SystemTime::now(),
            });
        }
        families.extend(summary_families.into_values());

        // 添加内置指标
        if self.config.enable_app_metrics {
            families.extend(self.get_builtin_metrics().await);
        }

        Ok(families)
    }

    async fn reset(&self) -> ServiceResult<()> {
        // 重置所有原子指标
        let counters = self.counters.read().await;
        for counter in counters.values() {
            counter.reset();
        }

        // 清空其他结构
        self.metrics.write().await.clear();
        
        info!("All metrics have been reset");
        Ok(())
    }
}

impl EnhancedMetricsCollector {
    /// 获取内置指标
    async fn get_builtin_metrics(&self) -> Vec<MetricFamily> {
        let mut families = Vec::new();

        // 应用信息指标
        let app_info = self.app_info.read().await;
        if !app_info.is_empty() {
            let mut app_info_labels = app_info.clone();
            app_info_labels.insert("version".to_string(), "1.0.0".to_string());
            
            families.push(MetricFamily {
                name: "rustcloud_app_info".to_string(),
                help: "Application information".to_string(),
                metric_type: MetricType::Gauge,
                metrics: vec![Metric {
                    name: "rustcloud_app_info".to_string(),
                    help: "Application information".to_string(),
                    metric_type: MetricType::Gauge,
                    value: MetricValue::Gauge(1.0),
                    labels: app_info_labels,
                    timestamp: SystemTime::now(),
                }],
            });
        }

        // 活跃连接数
        families.push(MetricFamily {
            name: "rustcloud_active_connections".to_string(),
            help: "Number of active connections".to_string(),
            metric_type: MetricType::Gauge,
            metrics: vec![Metric {
                name: "rustcloud_active_connections".to_string(),
                help: "Number of active connections".to_string(),
                metric_type: MetricType::Gauge,
                value: MetricValue::Gauge(self.get_active_connections() as f64),
                labels: HashMap::new(),
                timestamp: SystemTime::now(),
            }],
        });

        families
    }
}